class Node:
    def __init__(self, id, neighbors):
        self.id = id
        self.neighbors = neighbors
        self.parent = None
        self.received_from = []

    def receive_wave(self, from_node):
        print(f"{self.id}: Received wave from {from_node.id}")
        self.received_from.append(from_node)
        if self.parent is None and from_node.id != 0:  # The initiator sends with id 0
            self.parent = from_node
            self.send_wave()

    def send_wave(self):
        if self.parent is None:
            print(f"{self.id}: Sending wave to {', '.join(str(neighbor.id) for neighbor in self.neighbors)} as initiator")
        else:
            print(f"{self.id}: Sending wave to {', '.join(str(neighbor.id) for neighbor in self.neighbors if neighbor != self.parent)}")
        for neighbor in self.neighbors:
            if neighbor != self.parent:
                neighbor.receive_wave(self)

    def check_completion(self):
        if set(self.received_from) == set(self.neighbors):
            print(f"{self.id}: Received wave from all neighbors, sending wave to parent {self.parent.id}")
            if self.parent is not None:
                self.parent.receive_wave(self)
            else:
                print(f"{self.id}: As initiator, I received all waves back")

def main():
    # Create nodes
    nodes = [Node(i, []) for i in range(6)]  # Node 0 is the initiator

    # Set up neighbors
    neighbors_info = [
        [],  # Initiator doesn't have neighbors
        [2, 3, 4],
        [1, 3],
        [1, 2, 4],
        [1, 3, 5],
        [4],
    ]
    for i in range(1, 6):
        nodes[i].neighbors = [nodes[j] for j in neighbors_info[i]]

    # Start the algorithm at the initiator
    nodes[1].send_wave()

    # Check for completion
    for node in nodes[1:]:
        node.check_completion()

if __name__ == "__main__":
    main()
